package engine

import (
	"log"
)

type ConcurrentEngine struct {
	Scheduler Scheduler
	WorkerCount int
}

type Scheduler interface {
	ReadyNotifier
	Submit(Request)
	WorkerChan() chan Request
	Run()
}

type ReadyNotifier interface {
	WorkerReady(chan Request)
}

func (engine *ConcurrentEngine) Run(seeds ...Request) {

	// in := make(chan Request)
	// engine.Scheduler.ConfigureMasterWorkerChan(in)
	engine.Scheduler.Run()

	out := make(chan ParseResult)
	for i:=0;i<engine.WorkerCount;i++{
		// createWorkerByInAndOut(in,out)
		createWorker(engine.Scheduler.WorkerChan(), out,engine.Scheduler)
	}

	for _,seed := range seeds {
		engine.Scheduler.Submit(seed)
	}

	itemCount:=0
	for{
		result:=<-out

		for _,item:=range result.Items{
			log.Printf("Got item #%d %v",itemCount,item)
			itemCount++
		}


		for _,request:=range result.Requests{
			engine.Scheduler.Submit(request)
		}
	}
}

func createWorker(workChan chan Request, out chan ParseResult,readyNotifier ReadyNotifier) {
	go func() {
		for{
			readyNotifier.WorkerReady(workChan)
			request:=<-workChan
			result, err := worker(request)
			if err != nil {
				continue
			}
			out <- result

		}
	}()
}


